#!/bin/bash

# ---------------------------------------------------------------------------
#
# 使用说明：
#
# 1: MAIN_CLASS 必须要与配对的 start.sh 文件中的 MAIN_CLASS 完全相同
#
# 2: 该脚本用于别的项目时只需要修改 MAIN_CLASS 即可使用
#
# 3: 注意：如果有其它项目的 MAIN_CLASS 与本项目一样则不能使用本脚本关闭服务
#         同理同一个项目使用了不同端口启动的，也会拥有相同的 MAIN_CLASS 值
#         也不能使用本脚本关闭服务，这种情况使用下面的命令先查 pid 值：
#            ps aux | grep java
#
#         确认好 pid 以后，使用 kill pid 关闭服务
#         
#         注意 kill 命令不要带 -9 这个参数，否则 jfinal 中的一些与服务关闭
#         有关的回调方法将不会被回调，例如 JFinalConfig.beforeJFinalStop()
#
# ---------------------------------------------------------------------------


## 创建打印文件夹，保存打印文件，日志文件不自动清理
folder_path=`pwd`/down 
if [ ! -d "$folder_path" ]; then
    mkdir  $folder_path
    echo "文件夹 $folder_path 已创建"
else
    echo "文件夹 $folder_path 已存在"
fi

## 生成内存快照
ps -ef | grep `pwd` | grep -v grep | awk '/-Xms/{print $2}' | while read pid; do jmap -dump:live,format=b,file=`pwd`/down/$(date +"%Y-%m-%d_%H-%M-%S")_jmap_内存.hprof $pid ; done

## 生成线程快照
ps -ef | grep `pwd` | grep -v grep | awk '/-Xms/ {print $2}' | while read pid; do jstack -l $pid >> /`pwd`/down/$(date +"%Y-%m-%d_%H-%M-%S")_jstack_CPU.prof ; done

## 打印内存占用最高的十个进程
ps -auxf | sort -nr -k 4 | head -10 >> /`pwd`/down/$(date +"%Y-%m-%d_%H-%M-%S")_内存排序.txt

## 打印CPU占用最高的十个进程
ps -auxf | sort -nr -k 3 | head -10 >> /`pwd`/down/$(date +"%Y-%m-%d_%H-%M-%S")_CPU排序.txt

## 打印堆信息
ps -ef | grep `pwd` | grep -v grep | awk '/-Xms/ {print $2}' | while read pid; do jmap -J-d64 -heap $pid >> /`pwd`/down/$(date +"%Y-%m-%d_%H-%M-%S")_jmap_堆信息.prof ; done

## 打印 class 内存
ps -ef | grep `pwd` | grep -v grep | awk '/-Xms/ {print $2}' | while read pid; do jmap -histo $pid >> /`pwd`/down/$(date +"%Y-%m-%d_%H-%M-%S")_jmap_class内存.txt ; done

echo "打印信息完成，开始关闭项目"





# 启动入口类，该脚本文件用于别的项目时要改这里
MAIN_CLASS=com.MainConfig

# kill 命令不使用 -9 参数时，项目被正常、温和地关闭，jfinal 项目中的回调会起作用
kill `pgrep -f ${MAIN_CLASS}` 2>/dev/null


## 怀疑是线程满了，无法执行自定义的 onStop，导致服务一直杀不掉，作了延时10秒强制杀死的处理
## 如果onStop 中没有任何操作，不一定需要这样处理，可以测试一下
sleep 2s
kill -9 `pgrep -f ${MAIN_CLASS}` 2>/dev/null


# 以下代码与上述代码等价
# kill $(pgrep -f ${MAIN_CLASS}) 2>/dev/null
